<template>
  <el-dialog
    v-model="visible"
    title="表单预览"
    width="60%"
    @close="$emit('close')"
  >
    <el-form
      ref="previewFormRef"
      :model="previewModel"
      :label-width="formConfig.labelWidth"
      :label-position="formConfig.labelPosition"
      :size="formConfig.size"
      :rules="previewRules"
    >
      <template v-for="item in formItems" :key="item.key">
        <!-- 栅格布局 -->
        <el-row v-if="item.type === 'grid'" :gutter="item.gutter || 0">
          <el-col
            v-for="(column, colIndex) in item.columns"
            :key="colIndex"
            :span="column.span"
          >
            <el-form-item
              v-for="childItem in column.children"
              :key="childItem.key"
              :label="childItem.label"
              :prop="childItem.field"
              :required="childItem.required"
              :label-width="childItem.labelWidth"
            >
              <!-- 栅格子组件渲染 -->
              <!-- 输入框 -->
              <el-input
                v-if="childItem.type === 'input'"
                v-model="previewModel[childItem.field]"
                :type="childItem.inputType || 'text'"
                :placeholder="childItem.placeholder"
                :disabled="childItem.disabled"
                :clearable="childItem.clearable"
                :maxlength="childItem.maxlength"
                :show-word-limit="childItem.showWordLimit"
                @input="handleEvent(childItem, 'input', $event)"
                @change="handleEvent(childItem, 'change', $event)"
                @focus="handleEvent(childItem, 'focus', $event)"
                @blur="handleEvent(childItem, 'blur', $event)"
                @click="handleEvent(childItem, 'click', $event)"
                @keydown="handleEvent(childItem, 'keydown', $event)"
                @keyup="handleEvent(childItem, 'keyup', $event)"
                @clear="handleEvent(childItem, 'clear', $event)"
              />

              <!-- 数字输入框 -->
              <el-input-number
                v-else-if="childItem.type === 'number'"
                v-model="previewModel[childItem.field]"
                :placeholder="childItem.placeholder"
                :min="childItem.min"
                :max="childItem.max"
                :step="childItem.step"
                :precision="childItem.precision"
                :step-strictly="childItem.stepStrictly"
                :controls-position="childItem.controlsPosition"
                :disabled="childItem.disabled"
                @input="handleEvent(childItem, 'input', $event)"
                @change="handleEvent(childItem, 'change', $event)"
                @focus="handleEvent(childItem, 'focus', $event)"
                @blur="handleEvent(childItem, 'blur', $event)"
                @click="handleEvent(childItem, 'click', $event)"
              />

              <!-- 选择器 -->
              <el-select
                v-else-if="childItem.type === 'select'"
                v-model="previewModel[childItem.field]"
                :placeholder="childItem.placeholder"
                :disabled="childItem.disabled"
                :clearable="childItem.clearable"
                :multiple="childItem.multiple"
                :filterable="childItem.filterable"
                :collapse-tags="childItem.collapseTags"
                :max-collapse-tags="childItem.maxCollapseTags || 1"
                :multiple-limit="childItem.multipleLimit || 0"
                @change="handleEvent(childItem, 'change', $event)"
                @focus="handleEvent(childItem, 'focus', $event)"
                @blur="handleEvent(childItem, 'blur', $event)"
                @click="handleEvent(childItem, 'click', $event)"
                @clear="handleEvent(childItem, 'clear', $event)"
                @visibleChange="handleEvent(childItem, 'visibleChange', $event)"
                @removeTag="handleEvent(childItem, 'removeTag', $event)"
              >
                <el-option
                  v-for="option in childItem.options"
                  :key="option.value"
                  :label="option.label"
                  :value="option.value"
                />
              </el-select>

              <!-- 级联选择器 -->
              <el-cascader
                v-else-if="childItem.type === 'cascader'"
                v-model="previewModel[childItem.field]"
                :options="childItem.options || []"
                :placeholder="childItem.placeholder"
                :disabled="childItem.disabled"
                :clearable="childItem.clearable !== undefined ? childItem.clearable : true"
                :filterable="childItem.filterable !== undefined ? childItem.filterable : false"
                :collapse-tags="childItem.collapseTags !== undefined ? childItem.collapseTags : false"
                :separator="childItem.separator || ' / '"
                :show-all-levels="childItem.showAllLevels !== undefined ? childItem.showAllLevels : true"
                :props="{
                  multiple: childItem.multiple !== undefined ? childItem.multiple : false,
                  expandTrigger: childItem.expandTrigger || 'click',
                  checkStrictly: childItem.checkStrictly !== undefined ? childItem.checkStrictly : false
                }"
                @change="handleEvent(childItem, 'change', $event)"
                @focus="handleEvent(childItem, 'focus', $event)"
                @blur="handleEvent(childItem, 'blur', $event)"
                @clear="handleEvent(childItem, 'clear', $event)"
                @visible-change="handleEvent(childItem, 'visibleChange', $event)"
                @remove-tag="handleEvent(childItem, 'removeTag', $event)"
                @expand-change="handleEvent(childItem, 'expandChange', $event)"
              />

              <!-- 单选框组 -->
              <el-radio-group
                v-else-if="childItem.type === 'radio'"
                v-model="previewModel[childItem.field]"
                :disabled="childItem.disabled"
                @change="handleEvent(childItem, 'change', $event)"
                @click="handleEvent(childItem, 'click', $event)"
              >
                <template v-if="childItem.buttonStyle">
                  <el-radio-button
                    v-for="option in childItem.options"
                    :key="option.value"
                    :value="option.value"
                  >
                    {{ option.label }}
                  </el-radio-button>
                </template>
                <template v-else>
                  <el-radio
                    v-for="option in childItem.options"
                    :key="option.value"
                    :value="option.value"
                    :border="childItem.border"
                  >
                    {{ option.label }}
                  </el-radio>
                </template>
              </el-radio-group>

              <!-- 多选框组 -->
              <el-checkbox-group
                v-else-if="childItem.type === 'checkbox'"
                v-model="previewModel[childItem.field]"
                :disabled="childItem.disabled"
                :min="childItem.min"
                :max="childItem.max"
                @change="handleEvent(childItem, 'change', $event)"
                @click="handleEvent(childItem, 'click', $event)"
              >
                <template v-if="childItem.buttonStyle">
                  <el-checkbox-button
                    v-for="option in childItem.options"
                    :key="option.value"
                    :value="option.value"
                  >
                    {{ option.label }}
                  </el-checkbox-button>
                </template>
                <template v-else>
                  <el-checkbox
                    v-for="option in childItem.options"
                    :key="option.value"
                    :value="option.value"
                    :border="childItem.border"
                  >
                    {{ option.label }}
                  </el-checkbox>
                </template>
              </el-checkbox-group>

              <!-- 日期选择器 -->
              <el-date-picker
                v-else-if="childItem.type === 'date'"
                v-model="previewModel[childItem.field]"
                :type="childItem.dateType"
                :format="childItem.format"
                :placeholder="childItem.placeholder"
                :disabled="childItem.disabled"
                :clearable="childItem.clearable"
                @change="handleEvent(childItem, 'change', $event)"
                @focus="handleEvent(childItem, 'focus', $event)"
                @blur="handleEvent(childItem, 'blur', $event)"
                @click="handleEvent(childItem, 'click', $event)"
              />

              <el-time-picker
                v-else-if="childItem.type === 'time'"
                v-model="previewModel[childItem.field]"
                :format="childItem.format"
                :placeholder="childItem.placeholder"
                :disabled="childItem.disabled"
                :clearable="childItem.clearable"
                @change="handleEvent(childItem, 'change', $event)"
                @focus="handleEvent(childItem, 'focus', $event)"
                @blur="handleEvent(childItem, 'blur', $event)"
                @click="handleEvent(childItem, 'click', $event)"
              />

              <!-- 开关 -->
              <el-switch
                v-else-if="childItem.type === 'switch'"
                v-model="previewModel[childItem.field]"
                :disabled="childItem.disabled"
                :active-text="childItem.activeText"
                :inactive-text="childItem.inactiveText"
                :active-value="childItem.activeValue"
                :inactive-value="childItem.inactiveValue"
                @change="handleEvent(childItem, 'change', $event)"
                @click="handleEvent(childItem, 'click', $event)"
              />

              <!-- 树形控件 -->
              <el-tree
                v-else-if="childItem.type === 'tree'"
                :ref="`tree_${childItem.field}`"
                :data="childItem.data || []"
                :node-key="childItem.nodeKey || 'id'"
                :show-checkbox="childItem.showCheckbox"
                :check-strictly="childItem.checkStrictly"
                :default-expand-all="childItem.defaultExpandAll"
                :expand-on-click-node="childItem.expandOnClickNode"
                :check-on-click-node="childItem.checkOnClickNode"
                :accordion="childItem.accordion"
                :indent="childItem.indent"
                :draggable="childItem.draggable"
                :lazy="childItem.lazy"
                @node-click="
                  (data, node, nodeComponent, event) =>
                    handleTreeEvent(
                      childItem,
                      'nodeClick',
                      data,
                      node,
                      nodeComponent,
                      event
                    )
                "
                @check-change="
                  (data, checked, indeterminate) =>
                    handleTreeEvent(
                      childItem,
                      'checkChange',
                      data,
                      checked,
                      indeterminate
                    )
                "
                @check="
                  (data, checkedInfo) =>
                    handleTreeEvent(childItem, 'check', data, checkedInfo)
                "
                @current-change="
                  (data, node) =>
                    handleTreeEvent(childItem, 'currentChange', data, node)
                "
                @node-expand="
                  (data, node, nodeComponent) =>
                    handleTreeEvent(
                      childItem,
                      'nodeExpand',
                      data,
                      node,
                      nodeComponent
                    )
                "
                @node-collapse="
                  (data, node, nodeComponent) =>
                    handleTreeEvent(
                      childItem,
                      'nodeCollapse',
                      data,
                      node,
                      nodeComponent
                    )
                "
              />

              <!-- 树形选择器 -->
              <el-tree-select
                v-else-if="childItem.type === 'treeselect'"
                v-model="previewModel[childItem.field]"
                :data="childItem.data || []"
                :node-key="childItem.nodeKey || 'value'"
                :multiple="childItem.multiple"
                :check-strictly="childItem.checkStrictly"
                :show-checkbox="childItem.showCheckbox"
                :placeholder="childItem.placeholder"
                :clearable="childItem.clearable"
                :disabled="childItem.disabled"
                :default-expand-all="childItem.defaultExpandAll"
                :filterable="childItem.filterable"
                :expand-on-click-node="childItem.expandOnClickNode"
                :check-on-click-node="childItem.checkOnClickNode"
                :accordion="childItem.accordion"
                @change="handleEvent(childItem, 'change', $event)"
                @visibleChange="handleEvent(childItem, 'visibleChange', $event)"
                @removeTag="handleEvent(childItem, 'removeTag', $event)"
                @clear="handleEvent(childItem, 'clear', $event)"
                @blur="handleEvent(childItem, 'blur', $event)"
                @focus="handleEvent(childItem, 'focus', $event)"
                @node-click="
                  (data, node, nodeComponent, event) =>
                    handleTreeEvent(
                      childItem,
                      'nodeClick',
                      data,
                      node,
                      nodeComponent,
                      event
                    )
                "
                @check-change="
                  (data, checked, indeterminate) =>
                    handleTreeEvent(
                      childItem,
                      'checkChange',
                      data,
                      checked,
                      indeterminate
                    )
                "
                @check="
                  (data, checkedInfo) =>
                    handleTreeEvent(childItem, 'check', data, checkedInfo)
                "
                @current-change="
                  (data, node) =>
                    handleTreeEvent(childItem, 'currentChange', data, node)
                "
                @node-expand="
                  (data, node, nodeComponent) =>
                    handleTreeEvent(
                      childItem,
                      'nodeExpand',
                      data,
                      node,
                      nodeComponent
                    )
                "
                @node-collapse="
                  (data, node, nodeComponent) =>
                    handleTreeEvent(
                      childItem,
                      'nodeCollapse',
                      data,
                      node,
                      nodeComponent
                    )
                "
              />

              <!-- 文本域 -->
              <el-input
                v-else-if="childItem.type === 'textarea'"
                v-model="previewModel[childItem.field]"
                type="textarea"
                :placeholder="childItem.placeholder"
                :disabled="childItem.disabled"
                :rows="childItem.rows"
                :maxlength="childItem.maxlength"
                :show-word-limit="childItem.showWordLimit"
                :autosize="childItem.autosize || false"
                @input="handleEvent(childItem, 'input', $event)"
                @change="handleEvent(childItem, 'change', $event)"
                @focus="handleEvent(childItem, 'focus', $event)"
                @blur="handleEvent(childItem, 'blur', $event)"
                @click="handleEvent(childItem, 'click', $event)"
                @keydown="handleEvent(childItem, 'keydown', $event)"
                @keyup="handleEvent(childItem, 'keyup', $event)"
              />

              <!-- 滑块 -->
              <el-slider
                v-else-if="childItem.type === 'slider'"
                v-model="previewModel[childItem.field]"
                :min="childItem.min || 0"
                :max="childItem.max || 100"
                :step="childItem.step || 1"
                :disabled="childItem.disabled || false"
                :show-input="childItem.showInput || false"
                :show-input-controls="childItem.showInputControls !== false"
                :show-stops="childItem.showStops || false"
                :show-tooltip="childItem.showTooltip !== false"
                :format-tooltip="childItem.formatTooltip"
                :range="childItem.range || false"
                :vertical="childItem.vertical || false"
                :height="childItem.vertical ? (childItem.height || '200px') : undefined"
                :marks="childItem.marks"
                @change="handleEvent(childItem, 'change', $event)"
                @input="handleEvent(childItem, 'input', $event)"
              />
            </el-form-item>
          </el-col>
        </el-row>

        <!-- 描述列表 -->
        <el-descriptions
          v-else-if="item.type === 'descriptions'"
          :title="item.title"
          :column="item.column || 3"
          :size="item.size"
          :border="item.border || false"
          :direction="item.direction || 'horizontal'"
          :extra="item.extra"
        >
          <el-descriptions-item
            v-for="(descItem, descIndex) in item.items || []"
            :key="descIndex"
            :label="descItem.label"
            :span="descItem.span || 1"
            :width="descItem.width"
            :min-width="descItem.minWidth"
            :align="descItem.align"
            :label-align="descItem.labelAlign"
            :class-name="descItem.className"
            :label-class-name="descItem.labelClassName"
          >
            {{ descItem.value }}
          </el-descriptions-item>
        </el-descriptions>

        <!-- 普通表单项 -->
        <el-form-item
          v-else
          :label="item.label"
          :prop="item.field"
          :required="item.required"
          :label-width="item.labelWidth"
        >
          <!-- 输入框 -->
          <el-input
            v-if="item.type === 'input'"
            v-model="previewModel[item.field]"
            :type="item.inputType || 'text'"
            :placeholder="item.placeholder"
            :disabled="item.disabled"
            :clearable="item.clearable"
            :maxlength="item.maxlength"
            :show-word-limit="item.showWordLimit"
            @input="handleEvent(item, 'input', $event)"
            @change="handleEvent(item, 'change', $event)"
            @focus="handleEvent(item, 'focus', $event)"
            @blur="handleEvent(item, 'blur', $event)"
            @click="handleEvent(item, 'click', $event)"
            @keydown="handleEvent(item, 'keydown', $event)"
            @keyup="handleEvent(item, 'keyup', $event)"
            @clear="handleEvent(item, 'clear', $event)"
          />

          <!-- 数字输入框 -->
          <el-input-number
            v-else-if="item.type === 'number'"
            v-model="previewModel[item.field]"
            :placeholder="item.placeholder"
            :min="item.min"
            :max="item.max"
            :step="item.step"
            :precision="item.precision"
            :step-strictly="item.stepStrictly"
            :controls-position="item.controlsPosition"
            :disabled="item.disabled"
            @input="handleEvent(item, 'input', $event)"
            @change="handleEvent(item, 'change', $event)"
            @focus="handleEvent(item, 'focus', $event)"
            @blur="handleEvent(item, 'blur', $event)"
            @click="handleEvent(item, 'click', $event)"
          />

          <!-- 选择器 -->
          <el-select
            v-else-if="item.type === 'select'"
            v-model="previewModel[item.field]"
            :placeholder="item.placeholder"
            :disabled="item.disabled"
            :clearable="item.clearable"
            :multiple="item.multiple"
            :filterable="item.filterable"
            :collapse-tags="item.collapseTags"
            :max-collapse-tags="item.maxCollapseTags || 1"
            :multiple-limit="item.multipleLimit || 0"
            @change="handleEvent(item, 'change', $event)"
            @focus="handleEvent(item, 'focus', $event)"
            @blur="handleEvent(item, 'blur', $event)"
            @click="handleEvent(item, 'click', $event)"
            @clear="handleEvent(item, 'clear', $event)"
            @visibleChange="handleEvent(item, 'visibleChange', $event)"
            @removeTag="handleEvent(item, 'removeTag', $event)"
          >
            <el-option
              v-for="option in item.options"
              :key="option.value"
              :label="option.label"
              :value="option.value"
            />
          </el-select>

          <!-- 级联选择器 -->
          <el-cascader
            v-else-if="item.type === 'cascader'"
            v-model="previewModel[item.field]"
            :options="item.options || []"
            :placeholder="item.placeholder"
            :disabled="item.disabled"
            :clearable="item.clearable !== undefined ? item.clearable : true"
            :filterable="item.filterable !== undefined ? item.filterable : false"
            :collapse-tags="item.collapseTags !== undefined ? item.collapseTags : false"
            :separator="item.separator || ' / '"
            :show-all-levels="item.showAllLevels !== undefined ? item.showAllLevels : true"
            :props="{
              multiple: item.multiple !== undefined ? item.multiple : false,
              expandTrigger: item.expandTrigger || 'click',
              checkStrictly: item.checkStrictly !== undefined ? item.checkStrictly : false
            }"
            @change="handleEvent(item, 'change', $event)"
            @focus="handleEvent(item, 'focus', $event)"
            @blur="handleEvent(item, 'blur', $event)"
            @clear="handleEvent(item, 'clear', $event)"
            @visible-change="handleEvent(item, 'visibleChange', $event)"
            @remove-tag="handleEvent(item, 'removeTag', $event)"
            @expand-change="handleEvent(item, 'expandChange', $event)"
          />

          <!-- 单选框组 -->
          <el-radio-group
            v-else-if="item.type === 'radio'"
            v-model="previewModel[item.field]"
            :disabled="item.disabled"
            @change="handleEvent(item, 'change', $event)"
            @click="handleEvent(item, 'click', $event)"
          >
            <template v-if="item.buttonStyle">
              <el-radio-button
                v-for="option in item.options"
                :key="option.value"
                :value="option.value"
              >
                {{ option.label }}
              </el-radio-button>
            </template>
            <template v-else>
              <el-radio
                v-for="option in item.options"
                :key="option.value"
                :value="option.value"
                :border="item.border"
              >
                {{ option.label }}
              </el-radio>
            </template>
          </el-radio-group>

          <!-- 多选框组 -->
          <el-checkbox-group
            v-else-if="item.type === 'checkbox'"
            v-model="previewModel[item.field]"
            :disabled="item.disabled"
            :min="item.min"
            :max="item.max"
            @change="handleEvent(item, 'change', $event)"
            @click="handleEvent(item, 'click', $event)"
          >
            <template v-if="item.buttonStyle">
              <el-checkbox-button
                v-for="option in item.options"
                :key="option.value"
                :value="option.value"
              >
                {{ option.label }}
              </el-checkbox-button>
            </template>
            <template v-else>
              <el-checkbox
                v-for="option in item.options"
                :key="option.value"
                :value="option.value"
                :border="item.border"
              >
                {{ option.label }}
              </el-checkbox>
            </template>
          </el-checkbox-group>

          <!-- 日期选择器 -->
          <el-date-picker
            v-else-if="item.type === 'date'"
            v-model="previewModel[item.field]"
            :type="item.dateType"
            :format="item.format"
            :placeholder="item.placeholder"
            :disabled="item.disabled"
            :clearable="item.clearable"
            @change="handleEvent(item, 'change', $event)"
            @focus="handleEvent(item, 'focus', $event)"
            @blur="handleEvent(item, 'blur', $event)"
            @click="handleEvent(item, 'click', $event)"
          />

          <el-time-picker
            v-else-if="item.type === 'time'"
            v-model="previewModel[item.field]"
            :format="item.format"
            :placeholder="item.placeholder"
            :disabled="item.disabled"
            :clearable="item.clearable"
            @change="handleEvent(item, 'change', $event)"
            @focus="handleEvent(item, 'focus', $event)"
            @blur="handleEvent(item, 'blur', $event)"
            @click="handleEvent(item, 'click', $event)"
          />

          <!-- 开关 -->
          <el-switch
            v-else-if="item.type === 'switch'"
            v-model="previewModel[item.field]"
            :disabled="item.disabled"
            :active-text="item.activeText"
            :inactive-text="item.inactiveText"
            :active-value="item.activeValue"
            :inactive-value="item.inactiveValue"
            @change="handleEvent(item, 'change', $event)"
            @click="handleEvent(item, 'click', $event)"
          />

          <!-- 树形控件 -->
          <el-tree
            v-else-if="item.type === 'tree'"
            :ref="`tree_${item.field}`"
            :data="item.data || []"
            :node-key="item.nodeKey || 'id'"
            :show-checkbox="item.showCheckbox"
            :check-strictly="item.checkStrictly"
            :default-expand-all="item.defaultExpandAll"
            :expand-on-click-node="item.expandOnClickNode"
            :check-on-click-node="item.checkOnClickNode"
            :accordion="item.accordion"
            :indent="item.indent"
            :draggable="item.draggable"
            :lazy="item.lazy"
            @node-click="
              (data, node, nodeComponent, event) =>
                handleTreeEvent(
                  item,
                  'nodeClick',
                  data,
                  node,
                  nodeComponent,
                  event
                )
            "
            @check-change="
              (data, checked, indeterminate) =>
                handleTreeEvent(
                  item,
                  'checkChange',
                  data,
                  checked,
                  indeterminate
                )
            "
            @check="
              (data, checkedInfo) =>
                handleTreeEvent(item, 'check', data, checkedInfo)
            "
            @current-change="
              (data, node) => handleTreeEvent(item, 'currentChange', data, node)
            "
            @node-expand="
              (data, node, nodeComponent) =>
                handleTreeEvent(item, 'nodeExpand', data, node, nodeComponent)
            "
            @node-collapse="
              (data, node, nodeComponent) =>
                handleTreeEvent(item, 'nodeCollapse', data, node, nodeComponent)
            "
          />

          <!-- 树形选择器 -->
          <el-tree-select
            v-else-if="item.type === 'treeselect'"
            v-model="previewModel[item.field]"
            :data="item.data || []"
            :node-key="item.nodeKey || 'value'"
            :multiple="item.multiple"
            :check-strictly="item.checkStrictly"
            :show-checkbox="item.showCheckbox"
            :placeholder="item.placeholder"
            :clearable="item.clearable"
            :disabled="item.disabled"
            :default-expand-all="item.defaultExpandAll"
            :expand-on-click-node="item.expandOnClickNode"
            :check-on-click-node="item.checkOnClickNode"
            :filterable="item.filterable"
            :accordion="item.accordion"
            :indent="item.indent"
            @change="handleEvent(item, 'change', $event)"
            @visibleChange="handleEvent(item, 'visibleChange', $event)"
            @removeTag="handleEvent(item, 'removeTag', $event)"
            @clear="handleEvent(item, 'clear', $event)"
            @blur="handleEvent(item, 'blur', $event)"
            @focus="handleEvent(item, 'focus', $event)"
            @node-click="
              (data, node, nodeComponent, event) =>
                handleTreeEvent(
                  item,
                  'nodeClick',
                  data,
                  node,
                  nodeComponent,
                  event
                )
            "
            @check-change="
              (data, checked, indeterminate) =>
                handleTreeEvent(
                  item,
                  'checkChange',
                  data,
                  checked,
                  indeterminate
                )
            "
            @check="
              (data, checkedInfo) =>
                handleTreeEvent(item, 'check', data, checkedInfo)
            "
            @current-change="
              (data, node) => handleTreeEvent(item, 'currentChange', data, node)
            "
            @node-expand="
              (data, node, nodeComponent) =>
                handleTreeEvent(item, 'nodeExpand', data, node, nodeComponent)
            "
            @node-collapse="
              (data, node, nodeComponent) =>
                handleTreeEvent(item, 'nodeCollapse', data, node, nodeComponent)
            "
          />

          <!-- 文本域 -->
          <el-input
            v-else-if="item.type === 'textarea'"
            v-model="previewModel[item.field]"
            type="textarea"
            :placeholder="item.placeholder"
            :disabled="item.disabled"
            :rows="item.rows"
            :maxlength="item.maxlength"
            :show-word-limit="item.showWordLimit"
            :autosize="item.autosize || false"
            @input="handleEvent(item, 'input', $event)"
            @change="handleEvent(item, 'change', $event)"
            @focus="handleEvent(item, 'focus', $event)"
            @blur="handleEvent(item, 'blur', $event)"
            @click="handleEvent(item, 'click', $event)"
            @keydown="handleEvent(item, 'keydown', $event)"
            @keyup="handleEvent(item, 'keyup', $event)"
          />

          <!-- 滑块 -->
          <el-slider
            v-else-if="item.type === 'slider'"
            v-model="previewModel[item.field]"
            :min="item.min || 0"
            :max="item.max || 100"
            :step="item.step || 1"
            :disabled="item.disabled || false"
            :show-input="item.showInput || false"
            :show-input-controls="item.showInputControls !== false"
            :show-stops="item.showStops || false"
            :show-tooltip="item.showTooltip !== false"
            :format-tooltip="item.formatTooltip"
            :range="item.range || false"
            :vertical="item.vertical || false"
            :height="item.vertical ? (item.height || '200px') : undefined"
            :marks="item.marks"
            @change="handleEvent(item, 'change', $event)"
            @input="handleEvent(item, 'input', $event)"
          />
        </el-form-item>

      </template>
    </el-form>
    <template #footer>
      <div
        style="
          display: flex;
          justify-content: space-between;
          align-items: center;
        "
      >
        <div>
          <!-- 验证相关按钮 -->
          <el-button
            v-if="formConfig?.events?.validate"
            type="info"
            @click="handleFormValidate"
            >验证表单</el-button
          >
          <el-button
            v-if="formConfig?.events?.validateField"
            type="warning"
            @click="handleFormValidateField"
            >验证字段</el-button
          >
          <el-button
            v-if="formConfig?.events?.clearValidate"
            @click="handleFormClearValidate"
            >清除验证</el-button
          >
        </div>
        <div>
          <!-- 主要操作按钮 -->
          <el-button @click="$emit('close')">关闭</el-button>
          <el-button v-if="formConfig.showResetButton" @click="resetForm"
            >重置</el-button
          >
          <el-button
            v-if="formConfig.showSubmitButton"
            type="primary"
            @click="submitPreview"
            >提交</el-button
          >
        </div>
      </div>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, computed, watch, nextTick } from "vue";
import { ElMessage } from "element-plus";

// Props
const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false,
  },
  formItems: {
    type: Array,
    default: () => [],
  },
  formConfig: {
    type: Object,
    default: () => ({}),
  },
  formModel: {
    type: Object,
    default: () => ({}),
  },
});

// Emits
const emit = defineEmits(["update:modelValue", "close"]);

// 预览表单引用
const previewFormRef = ref();

// 控制对话框显示
const visible = computed({
  get: () => props.modelValue,
  set: (value) => emit("update:modelValue", value),
});

// 预览表单数据
const previewModel = ref({});

// 预览表单验证规则
const previewRules = computed(() => {
  const rules = {};

  const addRules = (items) => {
    items.forEach((item) => {
      if (item.type === "grid") {
        // 处理栅格布局中的子组件
        item.columns?.forEach((column) => {
          if (column.children) {
            addRules(column.children);
          }
        });
      } else if (item.field) {
        const fieldRules = [];

        // 必填验证
        if (item.required) {
          const message = item.requiredMessage || `请输入${item.label}`;
          const trigger = item.trigger || "change";
          fieldRules.push({ required: true, message, trigger });
        }

        // 自定义验证规则
        if (item.validationRules && item.validationRules.length > 0) {
          item.validationRules.forEach((rule) => {
            // 整数验证不需要规则值
            const needsValue = rule.type !== "integer";
            if (rule.type && rule.message && (!needsValue || rule.value)) {
              const trigger = rule.trigger || "change";
              const validationRule = { trigger, message: rule.message };

              switch (rule.type) {
                // 数值验证规则
                case "min":
                  validationRule.validator = (ruleTemp, value, callback) => {
                    if (
                      value !== null &&
                      value !== undefined &&
                      value < parseFloat(rule.value)
                    ) {
                      callback(new Error(rule.message));
                    } else {
                      callback();
                    }
                  };
                  break;
                case "max":
                  validationRule.validator = (ruleTemp, value, callback) => {
                    if (
                      value !== null &&
                      value !== undefined &&
                      value > parseFloat(rule.value)
                    ) {
                      callback(new Error(rule.message));
                    } else {
                      callback();
                    }
                  };
                  break;
                case "integer":
                  validationRule.validator = (ruleTemp, value, callback) => {
                    if (
                      value !== null &&
                      value !== undefined &&
                      !Number.isInteger(value)
                    ) {
                      callback(new Error(rule.message));
                    } else {
                      callback();
                    }
                  };
                  break;
                case "precision":
                  validationRule.validator = (ruleTemp, value, callback) => {
                    if (value !== null && value !== undefined) {
                      const decimalPlaces = (
                        value.toString().split(".")[1] || ""
                      ).length;
                      if (decimalPlaces > parseInt(rule.value)) {
                        callback(new Error(rule.message));
                      } else {
                        callback();
                      }
                    } else {
                      callback();
                    }
                  };
                  break;
                // 选择器验证规则
                case "minItems":
                  validationRule.validator = (ruleTemp, value, callback) => {
                    if (
                      Array.isArray(value) &&
                      value.length < parseInt(rule.value)
                    ) {
                      callback(
                        new Error(rule.message || `至少选择${rule.value}项`)
                      );
                    } else {
                      callback();
                    }
                  };
                  break;
                case "maxItems":
                  validationRule.validator = (ruleTemp, value, callback) => {
                    if (
                      Array.isArray(value) &&
                      value.length > parseInt(rule.value)
                    ) {
                      callback(
                        new Error(rule.message || `最多选择${rule.value}项`)
                      );
                    } else {
                      callback();
                    }
                  };
                  break;
                // 文本验证规则
                case "minLength":
                  validationRule.min = parseInt(rule.value);
                  break;
                case "maxLength":
                  validationRule.max = parseInt(rule.value);
                  break;
                case "pattern":
                  validationRule.pattern = new RegExp(rule.value);
                  break;
                case "custom":
                  // 自定义验证函数
                  validationRule.validator = (ruleTemp, value, callback) => {
                    try {
                      const fn = new Function("value", "return " + rule.value);
                      if (fn(value)) {
                        callback();
                      } else {
                        callback(new Error(rule.message));
                      }
                    } catch (error) {
                      callback(new Error("验证规则错误"));
                    }
                  };
                  break;
              }

              fieldRules.push(validationRule);
            }
          });
        }

        if (fieldRules.length > 0) {
          rules[item.field] = fieldRules;
        }
      }
    });
  };

  addRules(props.formItems);
  return rules;
});

// 根据组件类型获取对应的Element Plus组件
const getComponentByType = (type) => {
  const componentMap = {
    input: "el-input",
    number: "el-input-number",
    select: "el-select",
    radio: "el-radio-group",
    checkbox: "el-checkbox-group",
    date: "el-date-picker",
    switch: "el-switch",
    textarea: "el-input",
  };
  return componentMap[type] || "el-input";
};

// 根据组件配置获取组件属性
const getComponentProps = (item) => {
  const baseProps = {
    placeholder: item.placeholder,
    disabled: item.disabled,
  };

  switch (item.type) {
    case "input":
      return {
        ...baseProps,
        clearable: item.clearable,
      };
    case "number":
      return {
        ...baseProps,
        min: item.min,
        max: item.max,
        step: item.step,
      };
    case "select":
      return {
        ...baseProps,
        clearable: item.clearable,
        multiple: item.multiple,
      };
    case "date":
      return {
        ...baseProps,
        type: item.dateType,
        clearable: item.clearable,
      };
    case "textarea":
      return {
        ...baseProps,
        type: "textarea",
        rows: item.rows,
      };
    default:
      return baseProps;
  }
};

// 监听对话框打开，初始化预览数据
watch(visible, (newVal) => {
  if (newVal) {
    const initModel = { ...props.formModel };

    // 初始化栅格布局中的子组件数据
    const initFormData = (items) => {
      items.forEach((item) => {
        if (item.type === "grid") {
          item.columns?.forEach((column) => {
            if (column.children) {
              initFormData(column.children);
            }
          });
        } else if (item.field && !(item.field in initModel)) {
          // 为没有初始值的字段设置默认值
          switch (item.type) {
            case "number":
              initModel[item.field] = 0;
              break;
            case "checkbox":
              initModel[item.field] = [];
              break;
            case "cascader":
              initModel[item.field] = item.multiple ? [] : "";
              break;
            case "switch":
              initModel[item.field] = false;
              break;
            case "tree":
              initModel[item.field] = [];
              break;
            case "treeselect":
              initModel[item.field] = "";
              break;
            default:
              initModel[item.field] = "";
          }
        }
      });
    };

    initFormData(props.formItems);
    previewModel.value = initModel;

    // 延迟清除验证状态，避免初始化时的验证警告
    nextTick(() => {
      if (previewFormRef.value) {
        previewFormRef.value.clearValidate();
      }
    });
  }
});

// 事件处理函数
const handleEvent = (item, eventType, ...args) => {
  if (item.events && item.events[eventType]) {
    try {
      // 创建一个函数来执行用户配置的事件代码
      const eventFunction = new Function(
        "value",
        "event",
        "formData",
        item.events[eventType]
      );
      eventFunction(
        previewModel.value[item.field],
        args[0],
        previewModel.value
      );
    } catch (error) {
      console.error(`执行${eventType}事件时出错:`, error);
    }
  }
};

// 重置表单
const resetForm = () => {
  if (props.formConfig?.events?.reset) {
    try {
      // 执行用户配置的重置事件代码
      const eventFunction = new Function(props.formConfig.events.reset);
      eventFunction();
    } catch (error) {
      console.error("执行重置事件时出错:", error);
    }
  }
  previewFormRef.value.resetFields();
};

// 提交预览表单
const submitPreview = async () => {
  try {
    await previewFormRef.value.validate();
    if (props.formConfig?.events?.submit) {
      // 执行用户配置的提交事件代码
      const eventFunction = new Function(props.formConfig.events.submit);
      eventFunction();
    }
    console.log("预览表单数据:", previewModel.value);
    ElMessage.success("表单提交成功！");
  } catch (error) {
    ElMessage.error("请检查表单数据");
  }
};

// 验证整个表单
const handleFormValidate = () => {
  previewFormRef.value.validate((valid, fields) => {
    if (valid) {
      console.log("表单验证通过");
      ElMessage.success("表单验证通过");
      if (props.formConfig?.events?.validate) {
        try {
          const eventFunction = new Function(props.formConfig.events.validate);
          eventFunction();
        } catch (error) {
          console.error("执行验证事件时出错:", error);
        }
      }
    } else {
      console.log("表单验证失败:", fields);
      ElMessage.error("表单验证失败，请检查输入");
    }
  });
};

// 验证指定字段
const handleFormValidateField = () => {
  // 获取第一个有验证规则的字段进行演示
  const firstField = Object.keys(previewModel.value)[0];
  if (firstField) {
    previewFormRef.value.validateField(firstField, (errorMessage) => {
      if (errorMessage) {
        console.log("字段验证失败:", errorMessage);
        ElMessage.error(`字段 ${firstField} 验证失败`);
      } else {
        console.log("字段验证通过");
        ElMessage.success(`字段 ${firstField} 验证通过`);
      }
      if (props.formConfig?.events?.validateField) {
        try {
          const eventFunction = new Function(
            props.formConfig.events.validateField
          );
          eventFunction();
        } catch (error) {
          console.error("执行字段验证事件时出错:", error);
        }
      }
    });
  }
};

// 清除表单验证状态
const handleFormClearValidate = () => {
  previewFormRef.value.clearValidate();
  console.log("已清除表单验证状态");
  ElMessage.info("已清除表单验证状态");
  if (props.formConfig?.events?.clearValidate) {
    try {
      const eventFunction = new Function(props.formConfig.events.clearValidate);
      eventFunction();
    } catch (error) {
      console.error("执行清除验证事件时出错:", error);
    }
  }
};

// 树形控件专用事件处理函数
const handleTreeEvent = (item, eventType, ...args) => {
  if (item.events && item.events[eventType]) {
    try {
      // 根据不同的事件类型，传递对应的参数
      let eventFunction;

      switch (eventType) {
        case "nodeClick":
          // nodeClick: (data, node, nodeComponent, event)
          eventFunction = new Function(
            "data",
            "node",
            "nodeComponent",
            "event",
            "formData",
            item.events[eventType]
          );
          eventFunction(args[0], args[1], args[2], args[3], previewModel.value);
          break;

        case "node-contextmenu":
          // node-contextmenu: (event, data, node, nodeComponent)
          eventFunction = new Function(
            "event",
            "data",
            "node",
            "nodeComponent",
            "formData",
            item.events[eventType]
          );
          eventFunction(args[3], args[0], args[1], args[2], previewModel.value);
          break;

        case "checkChange":
          // checkChange: (data, checked, indeterminate)
          eventFunction = new Function(
            "data",
            "checked",
            "indeterminate",
            "formData",
            item.events[eventType]
          );
          eventFunction(args[0], args[1], args[2], previewModel.value);
          break;

        case "check":
          // check: (data, checkedInfo)
          eventFunction = new Function(
            "data",
            "checkedInfo",
            "formData",
            item.events[eventType]
          );
          eventFunction(args[0], args[1], previewModel.value);
          break;

        case "currentChange":
          // currentChange: (data, node)
          eventFunction = new Function(
            "data",
            "node",
            "formData",
            item.events[eventType]
          );
          eventFunction(args[0], args[1], previewModel.value);
          break;

        case "nodeExpand":
        case "nodeCollapse":
          // nodeExpand/nodeCollapse: (data, node, nodeComponent)
          eventFunction = new Function(
            "data",
            "node",
            "nodeComponent",
            "formData",
            item.events[eventType]
          );
          eventFunction(args[0], args[1], args[2], previewModel.value);
          break;

        default:
          // 其他事件使用通用处理
          eventFunction = new Function(
            "value",
            "event",
            "formData",
            item.events[eventType]
          );
          eventFunction(
            previewModel.value[item.field],
            args[0],
            previewModel.value
          );
      }
    } catch (error) {
      console.error(`执行${eventType}事件时出错:`, error);
    }
  }
};
</script>

<style lang="less" scoped>
// 预览对话框样式可以根据需要添加
</style>
